package com.ncloud.resman.service.transform.impl;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ncloud.common.enmus.ResultEnum;
import com.ncloud.common.exception.UserException;
import com.ncloud.common.utils.DateUtils;
import com.ncloud.common.utils.excel.ExcelUtil;
import com.ncloud.resman.constant.ResConstant;
import com.ncloud.resman.entity.Brand;
import com.ncloud.resman.entity.CpeModel;
import com.ncloud.resman.entity.FirewallModel;
import com.ncloud.resman.entity.Model;
import com.ncloud.resman.entity.ServerModel;
import com.ncloud.resman.entity.ServerModelTemplate;
import com.ncloud.resman.entity.ServerUnit;
import com.ncloud.resman.entity.SwitchModel;
import com.ncloud.resman.mapper.DictMapper;
import com.ncloud.resman.service.BrandService;
import com.ncloud.resman.service.ModelService;
import com.ncloud.resman.service.ServerUnitService;
import com.ncloud.resman.service.transform.ModelTransService;
import com.xiaoleilu.hutool.poi.excel.ExcelReader;

@Service
public class ModelTransServiceImpl implements ModelTransService {
	
	@Autowired
	private ModelService modelService;
	@Autowired
	private DictMapper dictMapper;
	@Autowired
	private BrandService brandServcie;
	@Autowired
	private ServerUnitService unitService;

	@Override
	public void importModel(String eqptType,Long userId, InputStream inputStream) {
		if(ResConstant.EQPT_TYPE_SERVER.equals(eqptType)){
			importServerModel(eqptType, userId,inputStream);
		}else if(ResConstant.EQPT_TYPE_CPE.equals(eqptType)){
			importCpeModel(eqptType, userId,inputStream);
		}else if(ResConstant.EQPT_TYPE_SWITCH.equals(eqptType)){
			importSwitchModel(eqptType, userId,inputStream);
		}else if(ResConstant.EQPT_TYPE_FIREWALL.equals(eqptType)){
			importfirewallModel(eqptType, userId,inputStream);
		}else{
			throw new UserException("传入设备类型不存在eqptType="+eqptType);
		}
	}

	/**
	 * 1、获取传入参数转class
	 * 2、判断传入设备型号是否存在modelName
	 *   2.1 如果存在，判断硬盘型号，存在不处理，不存在插入硬盘数据
	 *   2.2 如果不存在，处理 内存、cpu、电源、硬盘、网卡等数据
	 * @param eqptType
	 * @param userId
	 * @param inputStream
	 */
	@Transactional
	private void importServerModel(String eqptType, Long userId, InputStream inputStream) {
		ExcelReader reader = com.xiaoleilu.hutool.poi.excel.ExcelUtil.getReader(inputStream);
		List<ServerModelTemplate> modelList = reader.readAll(ServerModelTemplate.class);
		//List<Object> modelList = ExcelUtil.getInstance().readExcel2ObjsByInputStream(inputStream, ServerModelTemplate.class);
		for (ServerModelTemplate sModel : modelList) {
			//ServerModelTemplate sModel = (ServerModelTemplate)x;
			sModel.setCreateUser(userId);
			sModel.setUpdateUser(userId);
			sModel.setCreateDate(new Date());
			sModel.setUpdateDate(new Date());
			Brand brand = brandServcie.getBrandByEqptTypeAndBrandName(eqptType,sModel.getBrandName());
			if(brand==null) throw new UserException("品牌不存在匹配记录【设备类型："+eqptType+",品牌名称:"+sModel.getBrandName()+"】");
			sModel.setBrandId(brand.getBrandId());
			sModel.setEqptType(eqptType);
			sModel.setEqptSpec(dictMapper.getDictKeyByIdAndValue("eqpt_spec", sModel.getEqptSpec()));
			// ServerModelTemplate 转 ServerModel
			ServerModel serverModel = new ServerModel();
			try {
				BeanUtils.copyProperties(serverModel, sModel);
				if(serverModel.getServerUnits()==null){
					serverModel.setServerUnits(new ArrayList<ServerUnit>());
				}
				// 判断型号是否存在
				Model model = modelService.getModelByModelName(eqptType,sModel.getBrandId(),sModel.getModelName());
				if(model == null){
					//处理CPU
					geneCpuInfo(serverModel,sModel);
					//处理内存
					geneRamInfo(serverModel,sModel);
					// 处理电源
					genePowerInfo(serverModel,sModel);
					// 处理网卡
					gengAdapterInfo(serverModel,sModel);
					// 处理硬盘
					geneDiskInfo(serverModel,sModel);
					
					modelService.insertServerModel(serverModel);
				}else{
					// 处理硬盘
					geneDiskInfo(serverModel,sModel);
					for (ServerUnit serverUnit : serverModel.getServerUnits()) {
						serverUnit.setModelId(model.getModelId());
						unitService.insertServerUnit(serverUnit);
					}
				}
				
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private void geneCpuInfo(ServerModel serverModel, ServerModelTemplate stModel) {
		ServerUnit unit = new ServerUnit();
		unit.setUnitType(ResConstant.UNIT_TYPE_CPU);
		Brand cpuBrand = brandServcie.getBrandByEqptTypeAndBrandName(ResConstant.UNIT_TYPE_CPU,stModel.getCpuBrand());
		if(cpuBrand==null) throw new UserException("CPU品牌不存在匹配记录【品牌名称:"+stModel.getCpuBrand()+"】");
		unit.setBrandId(cpuBrand.getBrandId());
		unit.setCapacity(stModel.getCpuCoreNum());
		unit.setAmount(stModel.getCpuNum().intValue());
		serverModel.getServerUnits().add(unit);
	}

	private void geneRamInfo(ServerModel serverModel, ServerModelTemplate stModel) {
		ServerUnit unit = new ServerUnit();
		unit.setUnitType(ResConstant.UNIT_TYPE_RAM);
		Brand brand = brandServcie.getBrandByEqptTypeAndBrandName(ResConstant.UNIT_TYPE_RAM,stModel.getRamBrand());
		if(brand==null)  throw new UserException("内存品牌不存在匹配记录【品牌名称:"+stModel.getRamBrand()+"】");
		unit.setBrandId(brand.getBrandId());
		unit.setCapacity(stModel.getRamCapacity());
		unit.setAmount(stModel.getRamNum().intValue());
		serverModel.getServerUnits().add(unit);
	}

	private void genePowerInfo(ServerModel serverModel, ServerModelTemplate stModel) {
		ServerUnit unit = new ServerUnit();
		unit.setUnitType(ResConstant.UNIT_TYPE_POWER);
		Brand brand = brandServcie.getBrandByEqptTypeAndBrandName(ResConstant.UNIT_TYPE_POWER,stModel.getPowerBrand());
		if(brand==null)  throw new UserException("电源品牌不存在匹配记录【品牌名称:"+stModel.getPowerBrand()+"】");
		unit.setBrandId(brand.getBrandId());
		unit.setAmount(stModel.getPowerNum().intValue());
		serverModel.getServerUnits().add(unit);
	}

	private void gengAdapterInfo(ServerModel serverModel, ServerModelTemplate stModel) {
		ServerUnit unit = new ServerUnit();
		unit.setUnitType(ResConstant.UNIT_TYPE_ADAPTER);
		Brand brand = brandServcie.getBrandByEqptTypeAndBrandName(ResConstant.UNIT_TYPE_ADAPTER,stModel.getAdapterBrand());
		if(brand==null)  throw new UserException("网卡品牌不存在匹配记录【品牌名称:"+stModel.getAdapterBrand()+"】");
		unit.setBrandId(brand.getBrandId());
		unit.setAmount(stModel.getAdapterNum().intValue());
		serverModel.getServerUnits().add(unit);
	}

	private void geneDiskInfo(ServerModel serverModel, ServerModelTemplate stModel) {
		ServerUnit unit = new ServerUnit();
		unit.setUnitType(ResConstant.UNIT_TYPE_DISK);
		Brand brand = brandServcie.getBrandByEqptTypeAndBrandName(ResConstant.UNIT_TYPE_DISK,stModel.getDiskBrand());
		if(brand==null)  throw new UserException("硬盘品牌不存在匹配记录【品牌名称:"+stModel.getDiskBrand()+"】");
		unit.setBrandId(brand.getBrandId());
		unit.setCapacity(stModel.getDiskCapacity());
		unit.setAmount(stModel.getDiskNum().intValue());
		serverModel.getServerUnits().add(unit);
	}

	@Transactional
	private void importSwitchModel(String eqptType, Long userId, InputStream inputStream) {
		List<Object> modelList = ExcelUtil.getInstance().readExcel2ObjsByInputStream(inputStream, SwitchModel.class);
		// 翻译字典表
		modelList.stream().forEach(x->{
			SwitchModel sModel = (SwitchModel)x;
			sModel.setCreateUser(userId);
			sModel.setUpdateUser(userId);
			sModel.setCreateDate(new Date());
			sModel.setUpdateDate(new Date());
			Brand brand = brandServcie.getBrandByEqptTypeAndBrandName(eqptType,sModel.getBrandName());
			if(brand==null) throw new UserException("品牌不存在匹配记录【设备类型："+eqptType+",品牌名称:"+sModel.getBrandName()+"】");
			sModel.setBrandId(brand.getBrandId());
			sModel.setEqptType(eqptType);
			sModel.setEqptSpec(dictMapper.getDictKeyByIdAndValue("eqpt_spec", sModel.getEqptSpec()));
			modelService.insertSwitchModel(sModel);
		});
	}

	@Transactional
	private void importfirewallModel(String eqptType, Long userId, InputStream inputStream) {
		List<Object> modelList = ExcelUtil.getInstance().readExcel2ObjsByInputStream(inputStream, FirewallModel.class);
		// 翻译字典表
		for (Object object : modelList) {
			FirewallModel fModel = (FirewallModel)object;
			fModel.setCreateUser(userId);
			fModel.setUpdateUser(userId);
			fModel.setCreateDate(new Date());
			fModel.setUpdateDate(new Date());
			Brand brand = brandServcie.getBrandByEqptTypeAndBrandName(eqptType,fModel.getBrandName());
			if(brand==null) throw new UserException("品牌不存在匹配记录【设备类型："+eqptType+",品牌名称:"+fModel.getBrandName()+"】");
			fModel.setBrandId(brand.getBrandId());
			fModel.setEqptType(eqptType);
			fModel.setEqptSpec(dictMapper.getDictKeyByIdAndValue("eqpt_spec", fModel.getEqptSpec()));
			modelService.insertModel(fModel);
		
		}
	}

	@Transactional
	private void importCpeModel(String eqptType, Long userId, InputStream inputStream) {
		List<Object> modelList = ExcelUtil.getInstance().readExcel2ObjsByInputStream(inputStream, CpeModel.class);
		// 翻译字典表
		for (Object object : modelList) {
			CpeModel cpeModel = (CpeModel)object;
			cpeModel.setCreateUser(userId);
			cpeModel.setUpdateUser(userId);
			cpeModel.setCreateDate(new Date());
			cpeModel.setUpdateDate(new Date());
			Brand brand = brandServcie.getBrandByEqptTypeAndBrandName(eqptType,cpeModel.getBrandName());
			if(brand==null) throw new UserException("品牌不存在匹配记录【设备类型："+eqptType+",品牌名称:"+cpeModel.getBrandName()+"】");
			cpeModel.setBrandId(brand.getBrandId());
			cpeModel.setEqptType(eqptType);
			cpeModel.setEqptSpec(dictMapper.getDictKeyByIdAndValue("eqpt_spec", cpeModel.getEqptSpec()));
			modelService.insertCpeModel(cpeModel);
		}
	}

	@Override
	public void exportModel(String eqptType, Long brandId, HttpServletResponse response, boolean templateFlag) {
		if(StringUtils.isBlank(eqptType)) throw new UserException(ResultEnum.PARAM_ERROR);
		List<Map<String, Object>> modelList = new ArrayList<Map<String,Object>>();
		@SuppressWarnings("rawtypes")
		Class clazz = null;
		if(ResConstant.EQPT_TYPE_SERVER.equals(eqptType)){
			if(!templateFlag){
				modelList = getServerModelList(eqptType, brandId);
			}
			clazz= ServerModelTemplate.class;
		}else if(ResConstant.EQPT_TYPE_CPE.equals(eqptType)){
			if(!templateFlag){
				modelList = getCpeModelList(eqptType, brandId);
			}
			clazz= CpeModel.class;
		}else if(ResConstant.EQPT_TYPE_SWITCH.equals(eqptType)){
			if(!templateFlag){
				modelList = getSwitchModelList(eqptType, brandId);
			}
			clazz= SwitchModel.class;
		}else if(ResConstant.EQPT_TYPE_FIREWALL.equals(eqptType)){
			if(!templateFlag){
				modelList = getFirewallModelList(eqptType, brandId);
			}
			clazz= FirewallModel.class;
		}
		OutputStream os = null;
		String title = "设备规格-"+dictMapper.getDictValueByIdAndKey("eqpt_type", eqptType)+(templateFlag?"模板":"");
        try {
        	response.setContentType("application/vnd.ms-excel");
        	response.setHeader("Content-disposition", "attachment;filename="+new String(title.getBytes("gb2312"), "ISO-8859-1")+".xls");
			os = response.getOutputStream();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Map<String, String> map = new HashMap<String, String>();
        map.put("title", title);
//        map.put("total", modelList.size()+" 条");
        map.put("date", DateUtils.getDate());
		ExcelUtil.getInstance().exportObj2ExcelByTemplate(map, "model-info-template.xls",
				os, modelList, clazz, true);
	}

	private List<Map<String, Object>> getServerModelList(String eqptType, Long brandId) {
		List<Map<String, Object>> modelList = modelService.findServerModelsByTypeAndBrandId(eqptType,brandId);
		// 翻译字典表
		final String type = dictMapper.getDictValueByIdAndKey("eqpt_type", eqptType);
		modelList.parallelStream().forEach(x->{
			x.put("eqptType",type);
			x.put("eqptSpec", dictMapper.getDictValueByIdAndKey("eqpt_spec", (String)x.get("eqptSpec")));
		});
		return modelList;
	}

	private List<Map<String, Object>> getSwitchModelList(String eqptType, Long brandId) {
		List<Map<String, Object>> modelList = modelService.findSwitchModelsByTypeAndBrandId(eqptType,brandId);
		// 翻译字典表
		final String type = dictMapper.getDictValueByIdAndKey("eqpt_type", eqptType);
		modelList.parallelStream().forEach(x->{
			x.put("eqptType",type);
			x.put("eqptSpec", dictMapper.getDictValueByIdAndKey("eqpt_spec", (String)x.get("eqptSpec")));
		});
		return modelList;
	}

	private List<Map<String, Object>> getFirewallModelList(String eqptType, Long brandId) {
		List<Map<String, Object>> modelList = modelService.findFirewallModelsByTypeAndBrandId(eqptType,brandId);
		// 翻译字典表
		final String type = dictMapper.getDictValueByIdAndKey("eqpt_type", eqptType);
		modelList.parallelStream().forEach(x->{
			x.put("eqptType",type);
			x.put("eqptSpec", dictMapper.getDictValueByIdAndKey("eqpt_spec", (String)x.get("eqptSpec")));
		});
		return modelList;
	}

	private List<Map<String, Object>> getCpeModelList(String eqptType, Long brandId) {
		List<Map<String, Object>> modelList = modelService.findCpeModelsByTypeAndBrandId(eqptType,brandId);
		// 翻译字典表
		final String type = dictMapper.getDictValueByIdAndKey("eqpt_type", eqptType);
		modelList.parallelStream().forEach(x->{
			x.put("eqptType",type);
			x.put("eqptSpec", dictMapper.getDictValueByIdAndKey("eqpt_spec", (String)x.get("eqptSpec")));
		});
		return modelList;
	}
}
